package QianFeng08.CollectionDemo;

import java.util.*;

/**
 * Collection接口：用于存储单个对象的集合
 * Collection层次结构中的根接口。Collection 表示一组对象，这些对象也称为collection的元素。
 * 一些collection允许有重复的元素，而另一些则不允许。一些collection是有序的，
 * 而另一些则是无序的。JDK 不提供此接口的任何直接实现:它提供更具体的子接口(如Set和List)实现。
 * 此接口通常用来传递collection,并在需要最大普遍性的地方操作这些collection.
 *
 * List接口：
 * 1、有序的，可以重复
 * 2、允许多个null元素
 * 3、常用的具体实现类：ArrayList、Vector、LinkedList
 *
 * 在实际开发中如何选择list的具体实现？
 * 1、安全性问题 Vector
 * 2、是否频繁插入，删除操作(LinkedList)
 * 3、是否是存储后遍历 ArrayList
 **/
public class ListDemo {
    public static void main(String[] args) {
        arrayList();
        Vector();
        linkedList();
    }

    /**
     * ArrayList
     * 1、实现原理：采用动态对象数组实现，默认的构造方法创建了一个空数组
     * 2、第一次添加元素，扩充容量为10，  之后的扩充算法：原来数据大小 + 原来数组的一半
     * 3、不适合进行删除或插入操作
     * 4、为了防止数组动态扩充次数过多，建议创建ArrayList时，给定初始容量
     * 5、多线程不安全，适合在单线程访问时使用
    **/
    private static void arrayList() {
        //使用集合来存储多个不同类型的元素（对象），那么在处理时会比较麻烦，实际开发中不建议使用
        List list = new ArrayList();
        list.add("常老师");
        list.add("周老师");
        list.add("黄老师");
        list.add(10);
        //这样使用，我们应该在一个集合中存储相同的类型对象
        List<String> list1 = new ArrayList<>();
        list1.add("常老师");
        list1.add("周老师");
        list1.add("黄老师");

        //Collections类提供的 sort() 方法可以对字符或数字列表进行排序。
        Collections.sort(list1);  // 排序

        //修改 ArrayList 中的元素可以使用 set() 方法
        list1.set(2, "Wiki"); // 第一个参数为索引位置，第二个为要修改的值

        //遍历集合
        int size = list1.size();
        for (int i = 0; i < size; i++) {
            System.out.println(list.get(i)); //get(i) 方法获取下标为i的元素
        }

        //判断集合中是否包含内容
        System.out.println(list1.contains("周老师")); //true
        //移除数组中的元素
        list1.remove("常老师"); //list1.remove(2);
        System.out.println(list1.size());

        //赋值给字符串数组再遍历
        String[] array = list1.toArray(new String[]{});
        for (String s : array) {
            System.out.println(s);
        }


    }

    /**
     * Vector
     * 1、实现原理：采用动态对象数组实现，默认构造方法创建了一个大小为10的对象数组
     * 2、扩充的算法：当增量为0时，扩充为原来大小 + 增量
     * 3、为了防止数组动态扩充次数过多，建议创建Vector时，给定初始容量
     * 4、线程安全，适合在多线程访问时使用，在单线程使用下效率较低
     **/
    private static void Vector() {
        //创建Vector对象的数组
        Vector<String> vector = new Vector<>();
        vector.add("常老师");
        vector.add("周老师");
        vector.add("黄老师");
        //数组的遍历
        for (String s : vector) {
            System.out.println(s);
        }
        /*int size = vector.size();
        for (int i = 0; i < size; i++) {
            System.out.println(vector.get(i)); //get(i) 方法获取下标为i的元素
        }*/
    }

    /**
     * LinkedList
     * 1、实现原理：采用双向的链表结构实现
     * 2、适合插入、删除操作，性能高
     **/
    private static void linkedList() {
        //创建LinkedList对象的数组
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("常老师");
        linkedList.add("周老师");
        linkedList.add("黄老师");
        //使用 addFirst() 在头部添加元素
        linkedList.addFirst("Wiki1");
        //使用 addLast() 在尾部添加元素
        linkedList.addLast("Wiki2");
        //使用 removeFirst() 移除头部元素
        linkedList.removeFirst();
        // 使用 removeLast() 移除尾部元素
        linkedList.removeLast();

        // 使用 getFirst() 获取头部元素
        System.out.println(linkedList.getFirst());
        // 使用 getLast() 获取尾部元素
        System.out.println(linkedList.getLast());


        //数组的遍历
        for (String s : linkedList) {
            System.out.println(s);
        }
        /*int size = linkedList.size();
        for (int i = 0; i < size; i++) {
            System.out.println(linkedList.get(i)); //get(i) 方法获取下标为i的元素
        }*/
    }


}
